﻿/*
                   _ooOoo_
                  o8888888o
                  88" . "88
                  (| -_- |)
                  O\  =  /O
               ____/`---'\____
             .'  \\|     |//  `.
            /  \\|||  :  |||//  \
           /  _||||| -:- |||||-  \
           |   | \\\  -  /// |   |
           | \_|  ''\---/''  |   |
           \  .-\__  `-`  ___/-. /
         ___`. .'  /--.--\  `. . __
      ."" '<  `.___\_<|>_/___.'  >'"".
     | | :  `- \`.;`\ _ /`;.`/ - ` : | |
     \  \ `-.   \_ __\ /__ _/   .-` /  /
======`-.____`-.___\_____/___.-`____.-'======
                   `=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
           佛祖保佑       永无BUG
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Gay.IDLL;


/***********************************************************************

 * Copyright (c) 2016 All Rights Reserved.
 * CLR版本： 4.0.30319.42000
 *机器名称：ROBIN-PC
 *命名空间：Gay.DLL
 *文件名：  BaseDAL
 *版本号：  V1.0.0.0
 *唯一标识：c57c2fc1-c6ab-4715-8595-2c4be8e15def
 *当前的用户域：ROBIN-PC
 *创建人：  luoda
 *电子邮箱：admin@52res.com
 *创建时间：2016/1/2 22:02:19
 *描述：
 *
 *=====================================================================
 *修改标记
 *修改时间：2016/1/2 22:02:19
 *修改人： luoda
 *版本号： V1.0.0.0
 *描述：
 *
***********************************************************************/

namespace Gay.DLL
{
    /// <summary>
    /// DLL基类
    /// </summary>
    public class BaseDAL<T> :InterfaceBaseDAL<T> where T : class
    {
        /// <summary>
        /// 当前数据上下文,由构造函数创建
        /// </summary>
        protected GayDbContext gContext;

        public T Add(T entity)
        {
            gContext.Entry<T>(entity).State = System.Data.Entity.EntityState.Added;
            gContext.SaveChanges();
            return entity;
        }

        public long Count(Expression<Func<T, bool>> predicate)
        {
            return gContext.Set<T>().Count(predicate);
        }

        public bool Delete(T entity)
        {
            gContext.Set<T>().Attach(entity);
            gContext.Entry<T>(entity).State = System.Data.Entity.EntityState.Deleted;
            return gContext.SaveChanges() > 0;
        }

        public bool Update(T entity)
        {
            gContext.Set<T>().Attach(entity);
            gContext.Entry<T>(entity).State = System.Data.Entity.EntityState.Modified;
            return gContext.SaveChanges() > 0;
        }

        public bool Exist(Expression<Func<T, bool>> anyLambda)
        {
            return gContext.Set<T>().Any(anyLambda);
        }

        public T Find(Expression<Func<T, bool>> whereLambda)
        {
            T _entity = gContext.Set<T>().FirstOrDefault<T>(whereLambda);
            return _entity;
        }

        public IQueryable<T> FindList(Expression<Func<T, bool>> whereLamdba, string orderName, bool isAsc)
        {
            var _list = gContext.Set<T>().Where(whereLamdba);
            _list = OrderBy(_list, orderName, isAsc);
            return _list;
        }

        public IQueryable<T> FindPageList(int pageIndex, int pageSize, out int totalRecord, Expression<Func<T, bool>> whereLamdba, string orderName, bool isAsc)
        {
            var _list = gContext.Set<T>().Where(whereLamdba);
            totalRecord = _list.Count();
            _list = OrderBy(_list, orderName, isAsc).Skip<T>((pageIndex - 1) * pageSize).Take<T>(pageSize);
            return _list;
        }

        /// <summary>
        /// 排序
        /// </summary>
        /// <param name="source">原IQueryable</param>
        /// <param name="propertyName">排序属性名</param>
        /// <param name="isAsc">是否正序</param>
        /// <returns>排序后的泛型IQueryable</returns>
        private IQueryable<T> OrderBy(IQueryable<T> source, string propertyName, bool isAsc)
        {
            if(source == null)
                throw new ArgumentNullException("source", "不能为空");
            if(string.IsNullOrEmpty(propertyName))
                return source;
            var _parameter = Expression.Parameter(source.ElementType);
            var _property = Expression.Property(_parameter, propertyName);
            if(_property == null)
                throw new ArgumentNullException("propertyName", "属性不存在");
            var _lambda = Expression.Lambda(_property, _parameter);
            var _methodName = isAsc ? "OrderBy" : "OrderByDescending";
            var _resultExpression = Expression.Call(typeof(Queryable), _methodName, new Type[] { source.ElementType, _property.Type }, source.Expression, Expression.Quote(_lambda));
            return source.Provider.CreateQuery<T>(_resultExpression);
        }

    }
}
